home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Tools 2
/
Amiga Tools 2.iso
/
grafik
/
bildanzeiger
/
seepix
/
source.lha
/
LoadIFF.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-11-27
|
12KB
|
426 lines
/**LoadIFF.c*************************************************************
* *
* SeePix -- by Hank Schafer *
* *
* SeePix is an IFF Picture Viewer. It works with Lo-Res, *
* Med-Res, Hi-Res, HAM, and EHB formats. I'm working on support *
* for X-Specs, and Anim5 formats. *
* *
* SeePix is based on a program by Olaf Barthel, called *
* 'LoadImage'. As released, LoadImage had a couple of bugs. *
* The Amiga-Key alternatives to menu use didn't all work. That's *
* been fixed. There were two separate print functions in LoadImage *
* which behaved exactly the same. The redundancy was eliminated. *
* LoadImage used the Topaz ROMFONT, and made no allowances for a *
* different system default font (under 2.04). I added a built-in *
* font. I've reworked the code considerably from the original *
* release, to allow for optimizations based on time and space. *
* *
* SeePix features a palette tool which allows "tweaking" of colors *
* prior to printing, allowing you to modify the color printout to *
* more closely resemble the original graphics (Blue is Blue, not *
* Purple). SeePix can be Iconified. SeePix features an ARP *
* interface. SeePix now uses the PathMaster File Selector. *
* *
************************************************************************
* *
* SeePix Copyright © 1992 by Hank Schafer; all rights reserved. *
* *
* This program is free software; you can redistribute it and/or *
* modify it under the terms of the GNU General Public License as *
* published by the Free Software Foundation, either version 1, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
* General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to: *
* Free Software Foundation, Inc. *
* 675 Massachusetts Ave. *
* Cambridge MA 02139, USA *
* *
**************** Special Function Copyright Notices ********************
* *
****LoadImage Copyright Notice: *
* *
* LoadImage is © Copyright 1988, 1989, 1990 by MXM, all rights *
* reserved, written by Olaf Barthel. No guarantees of any kind are *
* made that this program is 100% reliable. Use this program on *
* your own risk! *
* *
****Iconify Copyright Notice: *
* *
* Copyright 1987 by Leo L. Schwab. *
* Permission is hereby granted for use in any and all programs, *
* both Public Domain and commercial in nature, provided this *
* Copyright notice is left intact. *
* *
****ColorWindow (Palette) Copyright Notice: *
* *
* ColorWindow Routine -- Color Window Routines *
* from Book 1 of the Amiga Programmers' Suite by RJ Mical *
* *
* Copyright (C) 1986, 1987, Robert J. Mical *
* All Rights Reserved. *
* *
****PathMaster Copyright Notice: *
* *
* -------------------------------------------------------------------- *
* Copyright © 1989 Justin V. McCormick. All Rights Reserved. *
* -------------------------------------------------------------------- *
* *
* The PathMaster name is a trademark of Justin V. McCormick. *
* *
* PathMaster File Selector source and documentation written by: *
* *
* Justin V. McCormick. *
* Copyright © 1989 by Justin V. McCormick. *
* All Rights Reserved. *
* *
* -------------------------------------------------------------------- *
************************************************************************
* *
* Hope this is something you can use and enjoy. *
* *
************************************************************************/
/* LoadCMAP(), LoadHead() & LoadRast() functions */
/*
* LoadHead(FileName,BMHeader) :
*
* Does two jobs for us: Initializes the BitMapHeader and tries to figure out
* the Amiga ViewModes this file needs. Returns -1 on failure, not NULL.
*/
extern struct GfxBase *GfxBase;
LONG
LoadHead(char *FileName, BitMapHeader * BMHeader)
{
FILE *ImageFile;
LONG ViewModes = NULL;
/* No such file? */
if (!(ImageFile = fopen(FileName, "r")))
return (-1);
/* No BMHD-Chunk? */
if (!FindChunk("BMHD", ImageFile)) {
fclose(ImageFile);
return (-1);
}
/* Read the header. */
fread(BMHeader, sizeof(BitMapHeader), 1, ImageFile);
/*
* Strange values, probably not a picture but a "mistake", or even a
* CMAP.
*/
if (BMHeader->nPlanes < 1 || BMHeader->nPlanes > 8) {
fclose(ImageFile);
return (-1);
}
/*
* If we don't find a CAMG chunk in the file we will have to guess the
* right ViewModes. This line takes care of the interlaced display mode.
*/
if (BMHeader->pageHeight > GfxBase->NormalDisplayRows)
ViewModes |= LACE;
/* Could it be HIRES? */
if (BMHeader->pageWidth >= 640)
ViewModes |= HIRES;
/*
* It is still much more likely to encounter a HAM picture than an EHB
* picture. If we are wrong with this assumption, the CAMG chunk will
* tell us (hope so).
*/
if (BMHeader->nPlanes == 6)
ViewModes |= HAM;
/* Hello out there, got any CAMG chunk? */
if (!FindChunk("CAMG", ImageFile)) {
fclose(ImageFile);
return (ViewModes);
}
/* Read it then. */
fread(&ViewModes, sizeof(LONG), 1, ImageFile);
/* Mask out all unwanted bits (thanks, Carolyn!). */
ViewModes &= (~(SPRITES | VP_HIDE | GENLOCK_AUDIO | GENLOCK_VIDEO) | 0xFFFF);
/* Finish it. */
fclose(ImageFile);
return (ViewModes);
}
/*
* LoadCMAP(FileName,ColorMap,MaxCol,BMHeader) :
*
* Will load an unsigned word array with the colors to be found in the CMAP
* chunk.
*/
LONG
LoadCMAP(char *FileName, UWORD * ColorMap, LONG MaxCol, BitMapHeader * BMHeader)
{
LONG i;
FILE *ColFile;
LONG R, G, B;
/* Are you there? */
if (!(ColFile = fopen(FileName, "r")))
return (0);
/* Black 'n white or color TV? */
if (!FindChunk("CMAP", ColFile)) {
fclose(ColFile);
return (0);
}
/* Correct it before the reader believes it! */
if (MaxCol < 2)
MaxCol = 1 << BMHeader->nPlanes;
/* A bit too large, innit? */
if (MaxCol > 32)
MaxCol = 32;
/* Read those colors. */
for (i = 0; i < MaxCol; i++) {
R = fgetc(ColFile) >> 4;
G = fgetc(ColFile) >> 4;
B = fgetc(ColFile) >> 4;
/* The transformation. */
ColorMap[i] = (R << 8) | (G << 4) | (B);
}
/* Finish it. */
fclose(ColFile);
return (MaxCol);
}
/*
* LoadRast(FileName,BitPlanes,BMHeader) :
*
* Will decompress the interleaved bitmap data into a set of bitplanes.
*/
UBYTE
LoadRast(char *FileName, PLANEPTR * BitPlanes, BitMapHeader * BMHeader)
{
LONG i, j, k;
UBYTE Value, SoFar, Compr, Depth;
BYTE ChkVal;
LONG Height, Width;
PLANEPTR Planes[9]; /* 9 for possible bitmask. */
FILE *PicFile;
BYTE *AuxBuff; /* Decompress in memory buffer. */
BYTE *AuxBuff2;
LONG AuxLength;
/* Clear the planes. */
for (i = 0; i < 9; i++)
Planes[i] = NULL;
/* Set up the working copies. */
Width = LineBytes(BMHeader->w);
Height = BMHeader->h;
Depth = BMHeader->nPlanes;
Compr = BMHeader->compression;
/* Is there something wrong in paradise? */
if (Compr > 1 || !BitPlanes)
return (FALSE);
/* Can we read it, please? */
if (!(PicFile = fopen(FileName, "r")))
return (FALSE);
/* No BODY? What is this? */
if (!(AuxLength = FindChunk("BODY", PicFile))) {
fclose(PicFile);
return (FALSE);
}
/*
* Copy the bitmap pointers since their contents will get changed.
*/
for (i = 0; i < Depth; i++)
Planes[i] = BitPlanes[i];
/*
* Very well, nobody told me that DPaint and Aegis Images are allowed to
* save their own home-brewn BODY chunks if the transparent color is
* nonzero or the stencil/behind function is used. In this case the
* interleaved plane data is immediately followed by a bitmask which is
* to clear out all unwanted pixels after the image is drawn. To support
* this attitude we increment the depth of the image to give the reader
* access to a blank pointer the bitmask will be sent to.
*/
if (BMHeader->masking == 1)
Depth++;
/*
* If we can allocate the memory buffer, we will decompress the image in
* memory rather than while reading it from disk.
*/
if (AuxBuff = (BYTE *) AllocMem(AuxLength, MEMF_PUBLIC)) {
/* Read the data. */
fread(AuxBuff, AuxLength, 1, PicFile);
/* Remember the buffer address. */
AuxBuff2 = AuxBuff;
/* No compression? */
if (Compr == 0) {
for (k = 0; k < Height; k++) {
for (j = 0; j < Depth; j++) {
if (Planes[j]) {
CopyMem(AuxBuff, Planes[j], Width);
Planes[j] += Width;
}
AuxBuff += Width;
}
}
}
/* ByteRun compression? */
if (Compr == 1) {
for (k = 0; k < Height; k++) {
for (j = 0; j < Depth; j++) {
for (SoFar = 0; SoFar < Width;) {
ChkVal = *AuxBuff;
AuxBuff++;
if (ChkVal > 0) {
if (Planes[j]) {
CopyMem(AuxBuff, Planes[j], ChkVal + 1);
Planes[j] += ChkVal + 1;
}
AuxBuff += ChkVal + 1;
SoFar += ChkVal + 1;
} else {
if (ChkVal != -128) {
Value = *AuxBuff;
AuxBuff++;
for (i = 0; i <= -ChkVal; i++) {
if (Planes[j]) {
*Planes[j] = Value;
Planes[j]++;
}
SoFar++;
}
}
}
}
}
}
}
/* Free the auxilary buffer. */
FreeMem(AuxBuff2, AuxLength);
goto Quit;
}
/* No compression, take the data as is. */
if (Compr == 0) {
for (k = 0; k < Height; k++) {
for (j = 0; j < Depth; j++) {
if (Planes[j]) {
fread(Planes[j], Width, 1, PicFile);
Planes[j] += Width;
} else
fseek(PicFile, Width, 1);
}
}
}
/* ByteRun1 compression, efficient but tricky. */
if (Compr == 1) {
for (k = 0; k < Height; k++) {
for (j = 0; j < Depth; j++) {
for (SoFar = 0; SoFar < Width;) {
ChkVal = fgetc(PicFile);
/* Read the next bytes. */
if (ChkVal > 0) {
if (Planes[j]) {
fread(Planes[j], ChkVal + 1, 1, PicFile);
Planes[j] += ChkVal + 1;
} else
fseek(PicFile, ChkVal + 1, 1);
SoFar += ChkVal + 1;
} else {
/*
* Set the memory to this value.
*/
if (ChkVal != -128) {
Value = fgetc(PicFile);
for (i = 0; i <= -ChkVal; i++) {
if (Planes[j]) {
*Planes[j] = Value;
Planes[j]++;
}
SoFar++;
}
}
}
}
}
}
}
/* Finish it up. */
Quit:fclose(PicFile);
return (TRUE);
}